package app.core.model.impl;

import app.core.enums.MessageType;
import app.core.model.IMessage;

import java.util.*;

/**
 * 消息体
 * @author Guo.Yang
 * @version 1.0
 * @date 2022/12/31 14:41
 */
public class Message implements IMessage {
    private HashMap<String,String> data = new HashMap<>();

    public Message(){
        this(null);
    }



    private Message(String accept){
        data.put(TYPE, MessageType.ORDINARY.name());
        if (accept != null){
            String[] split = accept.split("-");
            for (String kv : split){
                String[] keyValue = kv.split("=");
                if (keyValue.length >= 2){
                    data.put(keyValue[0],keyValue[1]);
                }else {
                    data.put(keyValue[0],"");
                }
            }
        }
    }

    public static Message getInstance(String msg){
        Message message = new Message();
        message.setMessage(msg);
        return  message;
    }

    public static List<Message> create(String accept){
        ArrayList<Message> messages = new ArrayList<>();
        String[] split = accept.split("&");
        for(String s:split){
            if (!s.equals("")){
                messages.add(new Message(s));
            }
        }
        return messages;
    }

    /**
     * 设置数据
     * @param name 数据名
     * @param value 数据值
     */
    public  void  setData(String name, String value){
        if (name == null || value == null){
            return;
        }
        setDataList(name, Collections.singletonList(value));
    }

    /**
     * 构建值
     * 转义：
     * 使用@符号作为转义标识
     * 使用=符合连接key-value
     * 使用-连接多个key-value
     * 使用#连接value内的多个值（数组）
     * 使用&连接多个对象避免粘包问题
     * @param value
     * @return
     */
    protected String buildValue(String value){
        if (value ==null){
            return null;
        }
        return value.replaceAll("@","@0000")
                .replaceAll("=","@0001")
                .replaceAll("-","@0002")
                .replaceAll("#","@0003")
                .replaceAll("&","@0004");
    }

    /**
     * 解析值
     * @param value
     * @return
     */
    protected  String analysisValue(String value){
        if (value ==null){
            return null;
        }
        return value.replaceAll("@0004","&")
                .replaceAll("@0003","#")
                .replaceAll("@0002","-")
                .replaceAll("@0001","=")
                .replaceAll("@0000","@");
    }


    /**
     * 获取数据
     * @param name 数据名
     * @return
     */
    public  String getData(String name){
        return getDataList(name).get(0);
    }

    public List<String> getDataList(String name){
        String meta = Optional.ofNullable(data.get(name)).orElse("");
        String[] split = meta.split("#");
        ArrayList<String> list = new ArrayList<>();
        for (String temp : split){
            list.add(analysisValue(temp));
        }
        return list;
    }

    public void  setDataList(String name,List<String> list){
        StringBuilder builder = new StringBuilder();
        for(String temp : list){
            String value = buildValue(temp);
            builder.append(value);
            builder.append("#");
        }
        builder.deleteCharAt(builder.length() -1);
        data.put(name,builder.toString());
    }

    @Override
    public String getMessage() {
        return getData(MESSAGE);
    }

    @Override
    public void setMessage(String msg) {
        setMessages(Collections.singletonList(msg));
    }

    public void setMessages(List<String> msgList){
        setData(TIME, String.valueOf(System.currentTimeMillis()));
        setDataList(MESSAGE, msgList);
    }

    public List<String> getMessages(){
        return getDataList(MESSAGE);
    }

    @Override
    public MessageType getType() {
        return MessageType.valueOf(getData(TYPE));
    }

    @Override
    public void setType(MessageType type) {
        if (type != null){
            setData(TYPE,type.name());
        }
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder("&");
        data.forEach((k,v)->{
            builder.append(k);
            builder.append("=");
            builder.append(Optional.ofNullable(v).orElse(""));
            builder.append("-");
        });
        builder.deleteCharAt(builder.length() -1);
        return builder.toString();
    }
}
